/**
 * 如果运行时的不同部分需要共享和重用符号实例，那么可以用一个字符串作为键，在全局符号注册表中创建并重用符号。
 */
let fooGlobalSymbol = Symbol.for('foo');
console.log(typeof fooGlobalSymbol); // symbol
console.log(fooGlobalSymbol); // Symbol(foo)

/**
 * ymbol.for()对每个字符串键都执行幂等操作。
 * 第一次使用某个字符串调用时，它会检查全局运行时注册表，发现不存在对应的符号，于是就会生成一个新符号实例并添加到注册表中。
 * 后续使用相同字符串的调用同样会检查注册表，发现存在与该字符串对应的符号，然后就会返回该符号实例。
 */
// let fooGlobalSymbol = Symbol.for('foo'); // 创建新符号
let otherFooSymbol = Symbol.for('foo'); // 重用已有符号
console.log(fooGlobalSymbol === otherFooSymbol); // true

/**
 * 即使采用相同的符号描述，在全局注册表中定义的符号跟使用 Symbol()定义的符号也并不等同
 */
let localSymbol = Symbol('foo');
// let fooGlobalSymbol = Symbol.for('foo');
console.log(localSymbol === fooGlobalSymbol); // false

/**
 * 全局注册表中的符号必须使用字符串键来创建，因此作为参数传给 Symbol.for()的任何值都会被转换为字符串。此外，注册表中使用的键同时也会被用作符号描述。
 */
let emptyGlobalSymbol = Symbol.for();
// let fooGlobalSymbol = Symbol.for('foo');
console.log(emptyGlobalSymbol); // Symbol(undefined)
console.log(fooGlobalSymbol); // Symbol(foo)

/**
 * Symbol.keyFor() 方法返回全局符号注册表中 Symbol 实例对应的键,同时全局符号注册表中的键也是 Symbol 的描述.
 * 使用 Symbol.keyFor()来查询全局注册表，这个方法接收符号，返回该全局符号对应的字符串键。
 * 如果查询的不是全局符号，则返回 undefined。
 */
// 创建全局符号
let s = Symbol.for('foo');
console.log(Symbol.keyFor(s)); // foo

// 合建普通符号
let s2 = Symbol('bar');
console.log(Symbol.keyFor(s2)); // undefined

// 如果传给 Symbol.keyFor()的不是符号，则该方法抛出 TypeError
Symbol.keyFor(123); // TypeError: 123 is not a symbol
